package info.niwota.ziplock;

import info.niwota.ziplock.zip.CryptoUtils;

import java.security.Key;
import java.util.Arrays;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.Toast;

/**
 * @author qiangli
 * 
 */
public final class Dialogs {
	private static final String HELP_URI = "file:///android_asset/help.html";
	protected static final String TAG = "Dialogs";

	public static Dialog createDeleteDialog(final BaseActivity ctx) {
		OnClickListener cl = new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case DialogInterface.BUTTON_POSITIVE:
					try {
						ctx.deleteZip();
					} catch (Exception e) {
						Toast.makeText(ctx, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
						e.printStackTrace();
					}
					break;
				default:
				}
			}
		};
		AlertDialog.Builder b = new AlertDialog.Builder(ctx);
		b.setIcon(android.R.drawable.ic_dialog_alert);
		// default title to reserve space or the title will invisible
		b.setTitle(R.string.action_delete);
		b.setMessage(R.string.text_are_your_sure);
		b.setPositiveButton(android.R.string.ok, cl);
		b.setNegativeButton(android.R.string.cancel, cl);
		//
		return b.create();
	}

	public static Dialog createLoginDialog(final BaseActivity ctx) {
		LayoutInflater li = LayoutInflater.from(ctx);
		final View v = li.inflate(R.layout.dia_login, null);
		final DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				try {
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						EditText et = (EditText) v
								.findViewById(R.id.dia_login_password);
						String pwd = et.getText().toString();
						et.setText(null);
						ctx.login(pwd);
						return;
					default:
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		AlertDialog.Builder b = new AlertDialog.Builder(ctx);
		b.setView(v);
		b.setTitle(R.string.action_login);
		b.setPositiveButton(android.R.string.ok, l);
		b.setNegativeButton(android.R.string.cancel, l);
		return b.create();
	}

	public static Dialog createPasswordDialog(final BaseActivity ctx) {
		LayoutInflater li = LayoutInflater.from(ctx);
		final View v = li.inflate(R.layout.dia_pwd, null);
		final EditText ot = (EditText) v.findViewById(R.id.dia_old_password);
		final EditText st = (EditText) v.findViewById(R.id.dia_set_password);

		final DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				try {
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						final String hash = Preferences.getLockHash(ctx);
						String old = ot.getText().toString();
						String pwd = st.getText().toString();
						ot.setText(null);
						st.setText(null);

						if (verify(old, hash)) {
							change(old, pwd);
							// pwd change wont affect the key in the store
							Toast.makeText(ctx, R.string.msg_pwd_changed,
									Toast.LENGTH_SHORT).show();
						} else {
							Toast.makeText(ctx, R.string.msg_pwd_invalid,
									Toast.LENGTH_SHORT).show();
							return;
						}

						return;
					default:
					}
				} catch (Exception e) {
					Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_SHORT)
							.show();
					e.printStackTrace();
				}
			}

			private boolean verify(String pwd, String hash) throws Exception {
				if (TextUtils.isEmpty(pwd)) {
					return false;
				}
				String d = CryptoUtils.digest(pwd);
				return d.equals(hash);
			}

			private void change(String old, String pwd) throws Exception {
				String[] ka = Preferences.getLockKey(ctx);
				ka[0] = old;
				Key skey = CryptoUtils.unwrap(ka);
				String salt = CryptoUtils.salt();
				String wrapped = CryptoUtils.wrap(pwd, salt, skey);
				String[] sa = new String[] { "X", salt, wrapped };
				Preferences.putLockKey(ctx, sa);
				//
				String d = CryptoUtils.digest(pwd);
				Preferences.putLockHash(ctx, d);
			}
		};
		AlertDialog.Builder b = new AlertDialog.Builder(ctx);
		b.setView(v);
		b.setTitle(R.string.action_changepass);
		b.setPositiveButton(android.R.string.ok, l);
		b.setNegativeButton(android.R.string.cancel, l);
		return b.create();
	}

	public static Dialog createSetPasswordDialog(final BaseActivity ctx) {
		LayoutInflater li = LayoutInflater.from(ctx);
		final View v = li.inflate(R.layout.dia_setpwd, null);
		final EditText st = (EditText) v.findViewById(R.id.dia_set_password);

		final DialogInterface.OnClickListener l = new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				try {
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						String pwd = st.getText().toString();
						st.setText(null);

						set(pwd);
						//
						Toast.makeText(ctx, R.string.msg_pwd_set,
								Toast.LENGTH_SHORT).show();
						return;
					default:
					}
				} catch (Exception e) {
					Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_SHORT)
							.show();
					e.printStackTrace();
				}
			}

			private void set(String pwd) throws Exception {
				String[] ka = CryptoUtils.genKey(pwd);
				ka[0] = "X"; // clear pwd before saving
				Preferences.putLockKey(ctx, ka);
				if (Debug.DEBUG) {
					Log.d(TAG, "set, gen key: " + Arrays.asList(ka));
				}
				String d = CryptoUtils.digest(pwd);
				Preferences.putLockHash(ctx, d);
				if (Debug.DEBUG) {
					Log.d(TAG, "set, digest: " + d);
				}
			}
		};
		AlertDialog.Builder b = new AlertDialog.Builder(ctx);
		b.setView(v);
		b.setTitle(R.string.action_setpass);
		b.setPositiveButton(android.R.string.ok, l);
		b.setNegativeButton(android.R.string.cancel, l);
		return b.create();
	}

	private Dialogs() {
	}

	public static ProgressDialog createProgressDialog(final Context ctx) {
		ProgressDialog pd = new ProgressDialog(ctx);
		pd.setMessage(ctx.getText(R.string.wait));
		pd.setIndeterminate(true);
		pd.setCancelable(true);
		return pd;
	}

	public static Dialog createHelpDialog(final Context ctx) {
		LayoutInflater f = LayoutInflater.from(ctx);
		final View v = f.inflate(R.layout.dia_help, null);
		WebView wv = (WebView) v.findViewById(R.id.webview);
		wv.loadUrl(HELP_URI);
		//
		AlertDialog.Builder b = new AlertDialog.Builder(ctx);

		b.setIcon(R.drawable.help);
		b.setTitle(R.string.label_help);
		b.setView(v);

		return b.create();
	}

}
